home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / Install / program files / Borland / BDS / 3.0 / Demos / Delphi.Net / CLR / Reflection / Reflect.ReflectNode.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2004-10-22  |  28.6 KB  |  988 lines

  1. unit Reflect.ReflectNode;
  2.  
  3. //
  4. // ReflectNode is a specialized version of a TreeViews TreeNode. Using
  5. // reflection, it adds leaf nodes as appropriate. For example, if a node
  6. // is an assembly, leaf nodes are added that correspond to all modules that
  7. // the assembly contains. These modules are then expanded to include type
  8. // information.
  9. //
  10. // Written by Rick Ross (http://rick-ross.com)
  11. //
  12.  
  13. interface
  14.  
  15. uses
  16.   SysUtils,
  17.   System.Reflection,
  18.   System.Text,
  19.   System.Windows.Forms;
  20.  
  21. type
  22.   // This exception is thrown when any type that is located within the
  23.   // Borland namespace is being ignored.
  24.   EBorlandNamespace = Exception;
  25.  
  26.   ReflectTreeNode = class(TreeNode)
  27.   private
  28.     FAttributes        : string;
  29.     FOtherInfo         : string;
  30.     theType            : System.Type;
  31.     theAssembly        : Assembly;
  32.     theModule          : Module;
  33.     theMethodInfo      : MethodInfo;
  34.     theConstructorInfo : ConstructorInfo;
  35.     thePropertyInfo    : PropertyInfo;
  36.     theFieldInfo       : FieldInfo;
  37.     theEventInfo       : EventInfo;
  38.  
  39.     // class variables
  40.     class var
  41.       FBindingFlags : BindingFlags;
  42.       FHideBorNameSpace : boolean;
  43.  
  44.     // class static method(s)
  45.     class function  GetDefaultBindingFlags : System.Reflection.BindingFlags; static;
  46.     class procedure SetBindingFlags( bf : BindingFlags ); static;
  47.  
  48.     // normal methods
  49.     procedure AddNode( anAssembly : Assembly; aModule : Module; aType : System.Type;
  50.                        mi : MethodInfo; ci : ConstructorInfo; pi : PropertyInfo;
  51.                        fi : FieldInfo; ei : EventInfo );
  52.  
  53.     function  BuildCustomAttributes( provider : ICustomAttributeProvider ) : string;
  54.     function  BuildParmInfo(pi : array of ParameterInfo) : string;
  55.     function  BuildVisibility(mb : MethodBase) : string;
  56.     function  BuildMethodSignature(mi : MethodInfo) : string;
  57.     function  GetType( curType : System.Type ) : string;
  58.  
  59.     procedure BuildClassOrInterfaceDef;
  60.  
  61.     function  BuildConstructor( ci : ConstructorInfo ) : string;
  62.     function  BuildPropertyInfo( pinfo : PropertyInfo ) : string;
  63.     function  BuildField( finfo : FieldInfo ) : string;
  64.     function  BuildEvent( einfo : EventInfo ) : string;
  65.  
  66.     function  BuildIntrinsicAttributes( attrs : string ) : string;
  67.  
  68.     function  GetIntrinsicAttributes( atype : System.Type     ) : string; overload;
  69.     function  GetIntrinsicAttributes( pinfo : PropertyInfo    ) : string; overload;
  70.     function  GetIntrinsicAttributes( finfo : FieldInfo       ) : string; overload;
  71.     function  GetIntrinsicAttributes( einfo : EventInfo       ) : string; overload;
  72.     function  GetIntrinsicAttributes( mb    : MethodBase      ) : string; overload;
  73.  
  74.     function IsBorlandNamespace( atype : System.Type ) : boolean;
  75.   public
  76.     // constructors
  77.     constructor Create( alabel      : string          ); overload;
  78.     constructor Create( anAppDomain : AppDomain       ); overload;
  79.     constructor Create( anAssembly  : Assembly        ); overload;
  80.     constructor Create( aModule     : Module          ); overload;
  81.     constructor Create( minfo       : MethodInfo      ); overload;
  82.     constructor Create( pinfo       : PropertyInfo    ); overload;
  83.     constructor Create( aType       : System.Type     ); overload;
  84.     constructor Create( cinfo       : ConstructorInfo ); overload;
  85.     constructor Create( finfo       : FieldInfo       ); overload;
  86.     constructor Create( einfo       : EventInfo       ); overload;
  87.  
  88.     // regular properties
  89.     property OtherInfo  : string read FOtherInfo;
  90.     property Attributes : string read FAttributes;
  91.  
  92.     // class properties
  93.     class property DefaultBindingFlags   : BindingFlags read GetDefaultBindingFlags;
  94.     class property TheBindingFlags       : BindingFlags write SetBindingFlags;
  95.     class property HideBorlandNamespace  : boolean      write FHideBorNameSpace;
  96.  
  97.   end;
  98.  
  99. implementation
  100.  
  101. //
  102. // Returns the default binding flags. Feel free to change as appropriate
  103. //
  104. class function ReflectTreeNode.GetDefaultBindingFlags : System.Reflection.BindingFlags;
  105. begin
  106.   Result := BindingFlags.Public    or
  107.             BindingFlags.NonPublic or
  108.             BindingFlags.Instance  or
  109.             BindingFlags.Static    or
  110.             // comment DeclaredOnly to see all methods,
  111.             // even inherited ones.
  112.             BindingFlags.DeclaredOnly;
  113. end;
  114.  
  115. class procedure ReflectTreeNode.SetBindingFlags( bf : BindingFlags );
  116. begin
  117.   FBindingFlags := bf;
  118. end;
  119.  
  120. procedure ReflectTreeNode.AddNode( anAssembly : Assembly; aModule : Module; aType : System.Type;
  121.                                     mi : MethodInfo; ci : ConstructorInfo; pi : PropertyInfo;
  122.                                     fi : FieldInfo; ei : EventInfo );
  123. begin
  124.   self.theAssembly        := anAssembly;
  125.   self.theModule          := aModule;
  126.   self.theType            := aType;
  127.   self.theMethodInfo      := mi;
  128.   self.theConstructorInfo := ci;
  129.   self.thePropertyInfo    := pi;
  130.   self.theFieldInfo       := fi;
  131.   self.theEventInfo       := ei;
  132. end;
  133.  
  134. //
  135. // BuildCustomAttributes retrieves any custom attributes from the given provider
  136. //
  137. function ReflectTreeNode.BuildCustomAttributes( provider : ICustomAttributeProvider ) : string;
  138. var
  139.   i : integer;
  140.   ret : StringBuilder;
  141.   custAttrib : array of System.Object;
  142.  
  143. begin
  144.   // more information can be obtained by reflecting each of xthe custAttrib object
  145.   ret := StringBuilder.Create('');
  146.  
  147.   custAttrib := provider.GetCustomAttributes(false);
  148.   if (Length(custAttrib) > 0) then
  149.   begin
  150.     ret.Append('[ ');
  151.  
  152.     for i:=0 to Length(custAttrib)-1 do
  153.     begin
  154.       ret.Append(custAttrib[i].ToString());
  155.       ret.Append(' ');
  156.     end;
  157.     ret.Append(']');
  158.   end;
  159.  
  160.   Result := ret.ToString();
  161. end;
  162.  
  163. //
  164. // BuildParmInfo builds a string that represents a parameter list.
  165. //
  166.  
  167. function ReflectTreeNode.BuildParmInfo(pi : array of ParameterInfo) : string;
  168. var
  169.   ret  : StringBuilder;
  170.   i    : integer;
  171.   name : string;
  172.   len  : integer;
  173.  
  174. begin
  175.   ret := StringBuilder.Create('');
  176.  
  177.   ret.Append('( ');
  178.  
  179.   len := Length(pi)-1;
  180.  
  181.   for i:=0 to len do
  182.   begin
  183.     //if (pi[i].IsIn) then
  184.     //  ret.Append('in ');
  185.  
  186.     if (pi[i].IsOut) then
  187.       ret.Append('var ');
  188.  
  189.     name := pi[i].Name;
  190.  
  191.     if (name = '') then
  192.       name := 'p' + Int32(i+1).ToString();
  193.     ret.Append( name );
  194.  
  195.     ret.Append( ' : ' + pi[i].ParameterType.FullName );
  196.  
  197.     if (i < len) then
  198.       ret.Append( ', ');
  199.   end;
  200.  
  201.   ret.Append(' )');
  202.   Result := ret.ToString();
  203. end;
  204.  
  205. //
  206. // BuildVisibility determines the visibility of a method.
  207. //
  208. function ReflectTreeNode.BuildVisibility(mb : MethodBase) : string;
  209. var
  210.   ret : StringBuilder;
  211.  
  212. begin
  213.   ret := StringBuilder.Create('');
  214.   if (mb.IsAssembly) then
  215.     ret.Append('private ');
  216.  
  217.   if (mb.IsPrivate) then
  218.     ret.Append('strict private ');
  219.  
  220.   // FamilyOrAssembly = Protected
  221.   if (mb.IsFamilyOrAssembly) then
  222.     ret.Append('protected ');
  223.  
  224.   if (mb.IsFamily) then
  225.     ret.Append('strict protected ');
  226.  
  227.   if (mb.IsPublic) then
  228.     ret.Append('public ');
  229.  
  230.   if (mb.IsStatic) then
  231.     ret.Append('class ');
  232.  
  233.   Result := ret.ToString();
  234. end;
  235.  
  236. //
  237. // BuildMethodSignature uses the information passed in to generate a string
  238. // representing the method
  239. //
  240.  
  241. function ReflectTreeNode.BuildMethodSignature(mi : MethodInfo) : string;
  242. var
  243.   ret     : StringBuilder;
  244.   oi      : StringBuilder;
  245.   IsFunc  : boolean;
  246.   rettype : StringBuilder;
  247.  
  248. begin
  249.   ret := StringBuilder.Create( BuildVisibility(mi) );
  250.   oi  := StringBuilder.Create('');
  251.  
  252.   // is this a function?
  253.   IsFunc := false;
  254.   rettype := StringBuilder.Create(mi.ReturnType.Name);
  255.  
  256.   if (rettype.ToString().Equals('Void')) then
  257.     ret.Append('procedure ')
  258.   else
  259.   begin
  260.     ret.Append('function ');
  261.     IsFunc := true;
  262.   end;
  263.  
  264.   ret.Append(mi.Name);
  265.   ret.Append( BuildParmInfo( mi.GetParameters() ));
  266.   if IsFunc then
  267.     ret.Append(' : (isfunc) ' + mi.ReturnType.Name + ';');
  268.  
  269.   if (mi.IsVirtual) then
  270.     ret.Append('virtual; ');
  271.  
  272.   if (mi.IsAbstract) then
  273.     ret.Append('abstract; ');
  274.  
  275.   if (mi.IsFinal) then
  276.     ret.Append('final; ');
  277.  
  278.   if (IsFunc) then
  279.     ret.Append(' ' + mi.ReturnType.Name + ' ');
  280.  
  281.   if (mi.IsConstructor) then
  282.     oi.Append('constructor ');
  283.  
  284.   FOtherInfo := oi.ToString();
  285.  
  286.   Result := ret.ToString();
  287. end;
  288.  
  289. //
  290. // GetType returns a string that represents the given type.
  291. //
  292.  
  293. function ReflectTreeNode.GetType( curType : System.Type ) : string;
  294. var
  295.   ret : string;
  296.  
  297. begin
  298.   if (curType.IsArray) then
  299.     ret := 'array '
  300.   else if (curType.IsClass) then
  301.     ret := 'class '
  302.   else if (curType.IsCOMObject) then
  303.     ret := 'Com Object '
  304.   else if (curType.IsEnum) then
  305.     ret := 'enum '
  306.   else if (curType.IsInterface) then
  307.     ret := 'interface '
  308.   else if (curType.IsPointer) then
  309.     ret := 'pointer '
  310.   else if (curType.IsPrimitive) then
  311.     ret := 'primative '
  312.   else if (curType.IsValueType) then
  313.     ret := 'value type '
  314.   else
  315.   begin
  316.     ret := 'other/unknown? ';
  317.     FOtherInfo := curType.FullName;
  318.   end;
  319.  
  320.   if (curType.IsClass) then
  321.     ret := curType.Name + ' = ' + ret + '( ' + curType.BaseType.FullName + ' )'
  322.   else
  323.     ret := ret + curType.FullName;
  324.  
  325.   Result := ret;
  326. end;
  327.  
  328. //
  329. // BuildConstructor returns a string representing the constructor
  330. //
  331.  
  332. function ReflectTreeNode.BuildConstructor( ci : ConstructorInfo ) : string;
  333. var
  334.   ret : StringBuilder;
  335.   oi  : StringBuilder;
  336.  
  337. begin
  338.   ret := StringBuilder.Create( BuildVisibility(ci) );
  339.   oi  := StringBuilder.Create('');
  340.  
  341.   ret.Append('Create');
  342.   ret.Append( BuildParmInfo( ci.GetParameters() ));
  343.  
  344.   if (ci.IsVirtual) then
  345.     ret.Append('virtual; ');
  346.  
  347.   if (ci.IsAbstract) then
  348.     ret.Append('abstract; ');
  349.  
  350.   if (ci.IsFinal) then
  351.     ret.Append('final; ');
  352.  
  353.   if (ci.IsSpecialName) then
  354.     oi.Append('specialname ');
  355.  
  356.   if (ci.IsAssembly) then
  357.     oi.Append('assembly ');
  358.  
  359.   if (ci.IsHideBySig) then
  360.     oi.Append('hidebysig ');
  361.  
  362.   self.FOtherInfo := oi.ToString();
  363.   Result := ret.ToString();
  364. end;
  365.  
  366. //
  367. // BuildClassOrInterface definition adds addtional nodes that represent
  368. // fields, constructors, methods, properties and events.
  369. //
  370.  
  371. procedure ReflectTreeNode.BuildClassOrInterfaceDef;
  372. var
  373.   constr   : array of ConstructorInfo;
  374.   methods  : array of MethodInfo;
  375.   propinfo : array of PropertyInfo;
  376.   fields   : array of FieldInfo;
  377.   events   : array of EventInfo;
  378.   i        : integer;
  379.  
  380. begin
  381.   // get the fields
  382.   fields := theType.GetFields( FBindingFlags );
  383.   for i:=0 to Length(fields)-1 do
  384.   begin
  385.     Self.Nodes.Add( ReflectTreeNode.Create( fields[i] ));
  386.   end;
  387.  
  388.   if (theType.IsClass) then
  389.   begin
  390.     // get constructors
  391.     constr := theType.GetConstructors( FBindingFlags );
  392.     for i:=0 to Length(constr)-1 do
  393.     begin
  394.       self.Nodes.Add( ReflectTreeNode.Create( constr[i] ));
  395.     end;
  396.   end;
  397.  
  398.   methods := theType.GetMethods( FBindingFlags );
  399.   for i:=0 to Length(methods)-1 do
  400.   begin
  401.     // skip property methods
  402.     if (not (methods[i].Name.StartsWith('get_')) and (not methods[i].Name.StartsWith('set_'))) then
  403.       self.Nodes.Add( ReflectTreeNode.Create( methods[i] ));
  404.   end;
  405.  
  406.   propInfo := theType.GetProperties( FBindingFlags );
  407.   for i:=0 to Length(propInfo)-1 do
  408.   begin
  409.     self.Nodes.Add( ReflectTreeNode.Create( propInfo[i] ));
  410.   end;
  411.  
  412.   events := theType.GetEvents( FBindingFlags );
  413.   for i:=0 to Length(events)-1 do
  414.   begin
  415.     self.Nodes.Add( ReflectTreeNode.Create( events[i] ) );
  416.   end;
  417. end;
  418.  
  419. //
  420. // BuildPropertyInfo returns the string representation of a property
  421. //
  422.  
  423. function ReflectTreeNode.BuildPropertyInfo( pinfo : PropertyInfo ) : string;
  424. var
  425.   ret : StringBuilder;
  426.   mi  : MethodInfo;
  427.   name : string;
  428.  
  429. begin
  430.   ret := StringBuilder.Create('public property ');
  431.   ret.Append(pinfo.Name.ToString());
  432.   ret.Append(' : ');
  433.   ret.Append(pinfo.PropertyType.ToString());
  434.  
  435.   if (pinfo.CanRead) then
  436.   begin
  437.     ret.Append(' read ');
  438.     mi := pinfo.GetGetMethod();
  439.     name := '<unknown Get Method>';
  440.     if (mi <> nil) then
  441.       name := mi.Name;
  442.  
  443.     ret.Append( name );
  444.     ret.Append(';');
  445.   end;
  446.  
  447.   if (pinfo.CanWrite) then
  448.   begin
  449.     ret.Append(' write ');
  450.     mi := pinfo.GetSetMethod();
  451.     name := '<unknown Set Method>';
  452.     if (mi <> nil) then
  453.       name := mi.Name;
  454.     ret.Append( name );
  455.     ret.Append(';');
  456.   end;
  457.  
  458.   Result := ret.ToString();
  459. end;
  460.  
  461. //
  462. // BuildField returns a string that represents a field
  463. //
  464.  
  465. function ReflectTreeNode.BuildField( finfo : FieldInfo ) : string;
  466. var
  467.   ret : StringBuilder;
  468.  
  469. begin
  470.   ret := StringBuilder.Create('');
  471.   if (finfo.IsAssembly) then
  472.     ret.Append('private ');
  473.  
  474.   if (finfo.IsPrivate) then
  475.     ret.Append('strict private ');
  476.  
  477.   // FamilyOrAssembly = Protected
  478.   if (finfo.IsFamilyOrAssembly) then
  479.     ret.Append('protected ');
  480.  
  481.   if (finfo.IsFamily) then
  482.     ret.Append('strict protected ');
  483.  
  484.   if (finfo.IsPublic) then
  485.     ret.Append('public ');
  486.  
  487.   if (finfo.IsStatic) then
  488.     ret.Append('class var ');
  489.  
  490.  
  491.   ret.Append( finfo.Name );
  492.   ret.Append( ' : ' );
  493.   ret.Append( finfo.FieldType.FullName );
  494.   ret.Append( ';' );
  495.   Result := ret.ToString();
  496. end;
  497.  
  498. //
  499. // BuildEvent returns a string representing the given event
  500. //
  501.  
  502. function  ReflectTreeNode.BuildEvent( einfo : EventInfo ) : string;
  503. var
  504.   ret : StringBuilder;
  505.   oi  : StringBuilder;
  506.  
  507. begin
  508.   ret := StringBuilder.Create('public property ');
  509.   oi  := StringBuilder.Create('');
  510.  
  511.   ret.Append( einfo.Name );
  512.   ret.Append( ' : ' );
  513.   ret.Append( einfo.EventHandlerType.FullName );
  514.   ret.Append( ';' );
  515.  
  516.   if (einfo.IsMulticast) then
  517.     oi.Append( 'multicast ');
  518.  
  519.   if (einfo.IsSpecialName) then
  520.     oi.Append( 'specialname ');
  521.  
  522.   self.FOtherInfo := oi.ToString();
  523.  
  524.   Result := ret.ToString();
  525. end;
  526.  
  527. function ReflectTreeNode.BuildIntrinsicAttributes( attrs : string ) : string;
  528. begin
  529.   if attrs <> '' then
  530.     Result := 'Intrinsic [' + attrs + ']'
  531.   else
  532.     Result := 'Intrinsic: none.';
  533. end;
  534.  
  535. //
  536. // GetIntrinsicAttributes returns a string representing any intrinsic (built-in)
  537. // attributes for the given type.
  538. //
  539.  
  540. function ReflectTreeNode.GetIntrinsicAttributes( atype : System.Type ) : string;
  541. var
  542.   ret        : StringBuilder;
  543.   mask       : TypeAttributes;
  544.  
  545.   function MaskToStr( mask : TypeAttributes ) : string;
  546.   begin
  547.     case mask of
  548.       TypeAttributes.VisibilityMask     : Result := 'VisibilityMask';
  549.       TypeAttributes.LayoutMask         : Result := 'LayoutMask';
  550.       TypeAttributes.ClassSemanticsMask : Result := 'ClassSemanticsMask';
  551.       TypeAttributes.StringFormatMask   : Result := 'StringFormatMask';
  552.       TypeAttributes.ReservedMask       : Result := 'ReservedMask';
  553.     else
  554.       Result := 'Unknown mask!';
  555.     end;
  556.   end;
  557.  
  558.   function HasAttrib( mask : TypeAttributes; testfor : TypeAttributes ) : boolean;
  559.   begin
  560.     Result := (aType.Attributes and mask and testfor) = testfor;
  561.   end;
  562.  
  563.   function GetAttrib( mask : TypeAttributes; testfor : TypeAttributes ) : string;
  564.   var
  565.     tmpStr : string;
  566.  
  567.   begin
  568.     // While this looks like it's just testing for notpublic
  569.     // it also checks AutoLayout and Class since they all have
  570.     // the same value (0)
  571.     if (testfor = TypeAttributes.NotPublic)  or
  572.        (testfor = TypeAttributes.AutoLayout) or
  573.        (testfor = TypeAttributes.ClassSemanticsMask) then
  574.     begin
  575.       case mask of
  576.         TypeAttributes.VisibilityMask :
  577.           if HasAttrib( mask, testfor ) then
  578.              Result := 'NotPublic ';
  579.         TypeAttributes.LayoutMask :
  580.           if HasAttrib( mask, testfor ) then
  581.              Result := 'AutoLayout ';
  582.         TypeAttributes.ClassSemanticsMask :
  583.           if HasAttrib( mask, testfor ) then
  584.              Result := 'class ';
  585.       end;
  586.     end
  587.     else if HasAttrib( mask, testfor ) then
  588.     begin
  589.       tmpStr := '';
  590.       case testfor of
  591.         TypeAttributes.Public            : tmpStr := 'Public ';
  592.         TypeAttributes.NestedPublic      : tmpStr := 'NestedPublic ';
  593.         TypeAttributes.NestedPrivate     : tmpStr := 'NestedPrivate ';
  594.         TypeAttributes.NestedFamily      : tmpStr := 'NestedFamily ';
  595.         TypeAttributes.NestedAssembly    : tmpStr := 'NestedAssembly ';
  596.         TypeAttributes.NestedFamANDAssem : tmpStr := 'NestedFamANDAssem ';
  597.         TypeAttributes.NestedFamORAssem  : tmpStr := 'NestedFamORAssem ';
  598.  
  599.         TypeAttributes.SequentialLayout  : tmpStr := 'SequentialLayout ';
  600.         TypeAttributes.ExplicitLayout    : tmpStr := 'ExplicitLayout ';
  601.  
  602.         TypeAttributes.Interface         : tmpStr := 'Interface ';
  603.  
  604.         TypeAttributes.Abstract          : tmpStr := 'Abstract ';
  605.         TypeAttributes.Sealed            : tmpStr := 'Sealed ';
  606.         TypeAttributes.SpecialName       : tmpStr := 'SpecialName ';
  607.         TypeAttributes.Import            : tmpStr := 'Import ';
  608.  
  609.         TypeAttributes.Serializable      : tmpStr := 'Serializable ';
  610.         TypeAttributes.BeforeFieldInit   : tmpStr := 'BeforeFieldInit ';
  611.  
  612.         TypeAttributes.UnicodeClass      : tmpStr := 'UnicodeClass ';
  613.         TypeAttributes.AutoClass         : tmpStr := 'AutoClass ';
  614.  
  615.         TypeAttributes.RTSpecialName     : tmpStr := 'RTSpecialName ';
  616.         TypeAttributes.HasSecurity       : tmpStr := 'HasSecurity ';
  617.       else
  618.         tmpStr := 'Unhandled testfor!' + System.Enum( testfor ).ToString() ;
  619.       end;
  620.       Result := tmpStr;
  621.     end
  622.     else
  623.       Result := '';
  624.   end;
  625.  
  626. begin
  627.   ret := StringBuilder.Create('');
  628.  
  629.   mask := TypeAttributes.VisibilityMask;
  630.   //ret.Append( GetAttrib( mask, TypeAttributes.NotPublic         ));
  631.   ret.Append( GetAttrib( mask, TypeAttributes.Public            ));
  632.   ret.Append( GetAttrib( mask, TypeAttributes.NestedPublic      ));
  633.   ret.Append( GetAttrib( mask, TypeAttributes.NestedPrivate     ));
  634.   ret.Append( GetAttrib( mask, TypeAttributes.NestedFamily      ));
  635.   ret.Append( GetAttrib( mask, TypeAttributes.NestedAssembly    ));
  636.   ret.Append( GetAttrib( mask, TypeAttributes.NestedFamANDAssem ));
  637.   ret.Append( GetAttrib( mask, TypeAttributes.NestedFamORAssem  ));
  638.  
  639.   mask := TypeAttributes.LayoutMask;
  640.   //ret.Append( GetAttrib( mask, TypeAttributes.AutoLayout       ));
  641.   ret.Append( GetAttrib( mask, TypeAttributes.SequentialLayout ));
  642.   ret.Append( GetAttrib( mask, TypeAttributes.ExplicitLayout   ));
  643.  
  644.   mask := TypeAttributes.ClassSemanticsMask;
  645.   //ret.Append( GetAttrib( mask, TypeAttributes.Class ));
  646.   ret.Append( GetAttrib( mask, TypeAttributes.Interface    ));
  647.  
  648.   ret.Append( GetAttrib( TypeAttributes.Abstract,        TypeAttributes.Abstract        ));
  649.   ret.Append( GetAttrib( TypeAttributes.Sealed,          TypeAttributes.Sealed          ));
  650.   ret.Append( GetAttrib( TypeAttributes.SpecialName,     TypeAttributes.SpecialName     ));
  651.   ret.Append( GetAttrib( TypeAttributes.Import,          TypeAttributes.Import          ));
  652.   ret.Append( GetAttrib( TypeAttributes.Serializable,    TypeAttributes.Serializable    ));
  653.   ret.Append( GetAttrib( TypeAttributes.BeforeFieldInit, TypeAttributes.BeforeFieldInit ));
  654.  
  655.   mask := TypeAttributes.StringFormatMask;
  656.   ret.Append( GetAttrib( mask, TypeAttributes.AnsiClass    ));
  657.   ret.Append( GetAttrib( mask, TypeAttributes.UnicodeClass ));
  658.   ret.Append( GetAttrib( mask, TypeAttributes.AutoClass    ));
  659.  
  660.   mask := TypeAttributes.ReservedMask;
  661.   ret.Append( GetAttrib( mask, TypeAttributes.RTSpecialName ));
  662.   ret.Append( GetAttrib( mask, TypeAttributes.HasSecurity   ));
  663.  
  664.   Result := ret.ToString();
  665. end;
  666.  
  667. //
  668. // GetIntrinsicAttributes returns a string representing any instrinsic
  669. // (built-in) attributes for the given property
  670. //
  671.  
  672. function ReflectTreeNode.GetIntrinsicAttributes( pinfo : PropertyInfo    ) : string;
  673.  
  674.   function HasAttrib( pattr : PropertyAttributes ) : boolean;
  675.   begin
  676.     Result := ( pinfo.Attributes and pattr ) = pattr;
  677.   end;
  678.  
  679.   function AttribToStr( pattr : PropertyAttributes ) : string;
  680.   begin
  681.     case pattr of
  682.       PropertyAttributes.HasDefault    : Result := 'HasDefault';
  683.       PRopertyAttributes.RTSpecialName : Result := 'RTSpecialName';
  684.       PropertyAttributes.SpecialName   : Result := 'SpecialName';
  685.     end;
  686.   end;
  687.  
  688.   function TestAttrib( testfor : PropertyAttributes ) : string;
  689.   begin
  690.     Result := '';
  691.     if HasAttrib( testfor ) then
  692.       Result := AttribToStr( testfor );
  693.   end;
  694.  
  695. begin
  696.   Result := '';
  697.   Result := Result + TestAttrib( PropertyAttributes.HasDefault    );
  698.   Result := Result + TestAttrib( PropertyAttributes.RTSpecialName );
  699.   Result := Result + TestAttrib( PropertyAttributes.SpecialName   );
  700. end;
  701.  
  702. //
  703. // GetIntrinsicAttributes returns a string representing any instrinsic
  704. // (built-in) attributes for the given field
  705. //
  706.  
  707. function ReflectTreeNode.GetIntrinsicAttributes( finfo : FieldInfo       ) : string;
  708. begin
  709.   // For even more attributes, see finfo.Attributes
  710.   Result := '';
  711.   if (finfo.IsInitOnly) then
  712.     Result := Result + 'initonly ';
  713.  
  714.   if (finfo.IsLiteral) then
  715.     Result := Result + 'literal ';
  716.  
  717.   if (finfo.IsNotSerialized) then
  718.     Result := Result + 'notserialized';
  719.  
  720.   if (finfo.IsPinvokeImpl) then
  721.     Result := Result + 'pinvoke ';
  722.  
  723.   if (finfo.IsSpecialName) then
  724.     Result := Result + 'specialname ';
  725. end;
  726.  
  727. //
  728. // GetIntrinsicAttributes returns a string representing any instrinsic
  729. // (built-in) attributes for the given event
  730. //
  731.  
  732. function ReflectTreeNode.GetIntrinsicAttributes( einfo : EventInfo       ) : string;
  733. begin
  734.   // More attributes are available in einfo.Attributes
  735.   Result := '';
  736.  
  737.   if einfo.IsMulticast then
  738.     Result := Result + 'multicast ';
  739.  
  740.   if einfo.IsSpecialName then
  741.     Result := Result + 'specialname ';
  742. end;
  743.  
  744. //
  745. // GetIntrinsicAttributes returns a string representing any instrinsic
  746. // (built-in) attributes for the given method
  747. //
  748.  
  749. function ReflectTreeNode.GetIntrinsicAttributes( mb    : MethodBase ) : string;
  750.  
  751.   function HasAttrib( testfor : MethodAttributes ) : boolean;
  752.   begin
  753.     Result := (mb.Attributes and testfor) = testfor;
  754.   end;
  755.  
  756.   function AttribToStr( attr : MethodAttributes ) : string;
  757.   begin
  758.     case attr of
  759.       MethodAttributes.HasSecurity      : Result := 'HasSecurity ';
  760.       MethodAttributes.HideBySig        : Result := 'HideBySig ';
  761.       MethodAttributes.PinvokeImpl      : Result := 'PInvokeImpl ';
  762.       MethodAttributes.RequireSecObject : Result := 'RequireSecObject ';
  763.       MethodAttributes.RTSpecialName    : Result := 'RTSpecialName ';
  764.       MethodAttributes.UnmanagedExport  : Result := 'UnmanagedExport ';
  765.     end;
  766.   end;
  767.  
  768.   function TestAttrib( testfor : MethodAttributes ) : string;
  769.   begin
  770.     Result := '';
  771.     if HasAttrib( testfor ) then
  772.       Result := AttribToStr( testfor );
  773.   end;
  774.  
  775. begin
  776.   Result := '';
  777.   Result := Result + TestAttrib( MethodAttributes.HasSecurity      );
  778.   Result := Result + TestAttrib( MethodAttributes.HideBySig        );
  779.   Result := Result + TestAttrib( MethodAttributes.PinvokeImpl      );
  780.   Result := Result + TestAttrib( MethodAttributes.RequireSecObject );
  781.   Result := Result + TestAttrib( MethodAttributes.RTSpecialName    );
  782.   Result := Result + TestAttrib( MethodAttributes.UnmanagedExport  );
  783. end;
  784.  
  785. //
  786. // IsBorlandNamespace determines if a given type is within the Borland
  787. // namespace.
  788. //
  789.  
  790. function ReflectTreeNode.IsBorlandNamespace( atype : System.Type ) : boolean;
  791. const
  792.   BORLAND_NS = 'Borland.';
  793.  
  794. begin
  795.   Result := false;
  796.   if atype = nil then
  797.     Exit;
  798.  
  799.   // does this fullname start with Borland.
  800.   Result := Pos( BORLAND_NS, atype.FullName ) = 1;
  801. end;
  802.  
  803. //
  804. // Use this constructor to add a simple label
  805. //
  806.  
  807. constructor ReflectTreeNode.Create( alabel : string );
  808. begin
  809.   inherited;
  810.  
  811.   AddNode( nil, nil, nil, nil, nil, nil, nil, nil );
  812.   self.Text := alabel;
  813. end;
  814.  
  815. //
  816. // Use this constructor to add an AppDomain
  817. //
  818.  
  819. constructor ReflectTreeNode.Create( anAppDomain : AppDomain );
  820. var
  821.   i : integer;
  822.   assems : array of Assembly;
  823.  
  824. begin
  825.   inherited Create;
  826.   self.Text := 'Currently loaded assemblies';
  827.   // we're not interested in adding the appdomain but we do want the
  828.   // assemblies that it contains...
  829.   assems := anAppDomain.GetAssemblies();
  830.   for i:=0 to Length(assems)-1 do
  831.   begin
  832.     self.Nodes.Add( ReflectTreeNode.Create( assems[i] ) );
  833.   end;
  834. end;
  835.  
  836. //
  837. // Use this constructor to add an Assembly
  838. //
  839.  
  840. constructor ReflectTreeNode.Create( anAssembly : Assembly );
  841. var
  842.   i : integer;
  843.   curMod : Module;
  844.  
  845. begin
  846.   inherited Create;
  847.  
  848.   AddNode( anAssembly, nil, nil, nil, nil, nil, nil, nil);
  849.   self.Text := anAssembly.GetName().Name;
  850.   FAttributes := BuildCustomAttributes(anAssembly);
  851.   FOtherInfo  := 'Location  : ' + anAssembly.Location + Environment.NewLine +
  852.                  'CodeBase  : ' + anAssembly.CodeBase + Environment.NewLine +
  853.                  'FullName  : ' + anAssembly.FullName + Environment.NewLine +
  854.                  'GAC?      : ' + BoolToStr(anAssembly.GlobalAssemblyCache,true);
  855.  
  856.   if assigned(anAssembly.EntryPoint) then
  857.   begin
  858.     FOtherInfo := FOtherInfo + Environment.NewLine +
  859.                  'EntryPoint: ' + anAssembly.EntryPoint.Name;
  860.   end;
  861.  
  862.  
  863.   //anAssembly.
  864.   for i:=0 to Length(anAssembly.GetModules())-1 do
  865.   begin
  866.     curMod := anAssembly.GetModules()[i];
  867.     self.Nodes.Add( ReflectTreeNode.Create( curMod ) );
  868.   end;
  869. end;
  870.  
  871. //
  872. // Use this constructor to add a Module
  873. //
  874.  
  875. constructor ReflectTreeNode.Create( aModule : Module );
  876. var
  877.   i : integer;
  878.   mi : MethodInfo;
  879.   curType : System.Type;
  880.  
  881. begin
  882.   inherited Create;
  883.  
  884.   AddNode( nil, aModule, nil, nil, nil, nil, nil, nil );
  885.   self.Text := aModule.Name;
  886.   FAttributes := BuildCustomAttributes(aModule);
  887.   self.Nodes.Add( ReflectTreeNode.Create('Global Methods') );
  888.  
  889.   for i:=0 to Length(aModule.GetMethods())-1 do
  890.   begin
  891.     mi := aModule.GetMethods()[i];
  892.     self.Nodes[0].Nodes.Add( ReflectTreeNode.Create( mi ));
  893.   end;
  894.  
  895.   self.Nodes.Add( ReflectTreeNode.Create('Types'));
  896.   for i:=0 to Length(aModule.GetTypes())-1 do
  897.   begin
  898.     curType := aModule.GetTypes()[i];
  899.     try
  900.       self.Nodes[1].Nodes.Add( ReflectTreeNode.Create( curType ) );
  901.     except
  902.       on EBorlandNamespace do
  903.       begin
  904.         // eat this exception, as we're expecting this when we're
  905.         // filtering out the borland namespace..
  906.       end;
  907.     end;
  908.   end;
  909. end;
  910.  
  911. // Use this constructor to add a method
  912.  
  913. constructor ReflectTreeNode.Create( minfo : MethodInfo );
  914. begin
  915.   inherited Create;
  916.  
  917.   AddNode( nil, nil, nil, minfo, nil, nil, nil, nil );
  918.   self.Text := BuildMethodSignature( minfo );
  919.   FAttributes := BuildIntrinsicAttributes( GetIntrinsicAttributes( minfo )) +
  920.                    Environment.NewLine + BuildCustomAttributes( minfo );
  921. end;
  922.  
  923. // Use this constructor to add a property
  924.  
  925. constructor ReflectTreeNode.Create( pinfo : PropertyInfo );
  926. begin
  927.   inherited Create;
  928.  
  929.   AddNode( nil, nil, nil, nil, nil, pinfo, nil, nil );
  930.   self.Text := BuildPropertyInfo( pinfo );
  931.   FAttributes := BuildIntrinsicAttributes( GetIntrinsicAttributes( pinfo )) +
  932.                    Environment.NewLine + BuildCustomAttributes( pinfo );
  933. end;
  934.  
  935. // Use this constructor to add a type
  936.  
  937. constructor ReflectTreeNode.Create( aType : System.Type );
  938. begin
  939.   inherited Create;
  940.  
  941.   if FHideBorNameSpace and IsBorlandNamespace( aType ) then
  942.     raise EBorlandNamespace.CreateFmt('Borland namespace! %s ',[aType.Fullname]);
  943.  
  944.   AddNode( nil, nil, aType, nil, nil, nil, nil, nil );
  945.   self.Text := GetType( aType );
  946.   FAttributes := BuildIntrinsicAttributes( GetIntrinsicAttributes( aType )) +
  947.                    Environment.NewLine + BuildCustomAttributes( aType );
  948.   if ((aType.IsClass) or (aType.IsInterface)) then
  949.     BuildClassOrInterfaceDef;
  950. end;
  951.  
  952. // Use this constructor to add a constructor
  953.  
  954. constructor ReflectTreeNode.Create( cinfo : ConstructorInfo );
  955. begin
  956.   inherited Create;
  957.  
  958.   AddNode( nil, nil, nil, nil, cinfo, nil, nil, nil );
  959.   self.Text := BuildConstructor( cinfo );
  960.   FAttributes := BuildIntrinsicAttributes( GetIntrinsicAttributes( cinfo )) +
  961.                    Environment.NewLine + BuildCustomAttributes( cinfo );
  962. end;
  963.  
  964. // Use this constructor to add an event
  965.  
  966. constructor ReflectTreeNode.Create( einfo : EventInfo );
  967. begin
  968.   inherited Create;
  969.  
  970.   AddNode( nil, nil, nil, nil, nil, nil, nil, einfo );
  971.   self.Text := BuildEvent( einfo );
  972.   FAttributes := BuildIntrinsicAttributes( GetIntrinsicAttributes( einfo )) +
  973.                    Environment.NewLine + BuildCustomAttributes( einfo );
  974. end;
  975.  
  976. // Use this constructor to add a field
  977.  
  978. constructor ReflectTreeNode.Create( finfo : FieldInfo );
  979. begin
  980.   inherited Create;
  981.     AddNode( nil, nil, nil, nil, nil, nil, finfo, nil );
  982.   Self.Text := BuildField( finfo );
  983.   FAttributes := BuildIntrinsicAttributes( GetIntrinsicAttributes( finfo )) +
  984.                    Environment.NewLine + BuildCustomAttributes( finfo );
  985. end;
  986.  
  987. end.
  988.